package com.myjob.serviceImpl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.myjob.dto.AuthTreeDto;
import com.myjob.entity.*;
import com.myjob.exception.DBOptionException;
import com.myjob.service.*;
import com.myjob.utils.UtilValidate;
import io.seata.spring.annotation.GlobalTransactional;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @author Chen Yuan
 * @create 2021-03-22  9:53
 */
@Service
public class AuthServiceImpl implements AuthService {
	@Autowired
	private RoleService roleService;
	@Autowired
	private ResourceService resourceService;
	@Autowired
	private RoleResourceRelService roleResourceRelService;

	@Override
	public List<AuthTreeDto> getAuthTree() {
		List<AuthTreeDto> authTree = new LinkedList<>();
		QueryWrapper<Resource> wrapper = new QueryWrapper<>();
		wrapper.orderByAsc("parent_id", "resource_order");

		List<Resource> resourceList = resourceService.list(wrapper);

		buildAuthTree(resourceList, authTree);

		return authTree;
	}

	@Override
	public List<String> getAllChecked(String roleId) {
		List<String> authCheck = new ArrayList<>();
		QueryWrapper<RoleResourceRel> wrapper = new QueryWrapper<>();
		wrapper.eq("role_id", roleId);
		List<RoleResourceRel> list = roleResourceRelService.list(wrapper);
		authCheck = list.stream()
						.map(roleResourceRel -> roleResourceRel.getResourceId().toString())
						.collect(Collectors.toList());
		return authCheck;
	}

	@Override
	public List<Role> getRoleList(){
		return roleService.list();
	}

	@Override
	@GlobalTransactional(rollbackFor = {DBOptionException.class, RuntimeException.class})
	public Boolean updateAuth(String roleId, List<String> roleList) {
		// 删除原来的
		QueryWrapper<RoleResourceRel> wrapper = new QueryWrapper<>();
		wrapper.eq("role_id", roleId);
		boolean remove = roleResourceRelService.remove(wrapper);

		if (!remove){
			throw new DBOptionException("删除原权限失败");
		}

		// 插入新的
		ArrayList<RoleResourceRel> roleResourceRels = new ArrayList<>();
		for (String s : roleList) {
			roleResourceRels.add(
					new RoleResourceRel(Long.parseLong(roleId),
							Long.parseLong(s))
			);
		}
		boolean save = roleResourceRelService.saveBatch(roleResourceRels);

		if (save){
			return true;
		}else {
			throw new DBOptionException("增加新权限失败");
		}
	}

	private void buildAuthTree(List<Resource> resourceList,
	                           List<AuthTreeDto> authTree){
		Map<String, AuthTreeDto> nodeMap = new LinkedHashMap<>();
		List<AuthTreeDto> nodeList = new ArrayList<>();

		for (Resource resource : resourceList) {
			String resourceName = resource.getResourceName();
			String id = String.valueOf(resource.getResourceId());
			String parentId = String.valueOf(resource.getParentId());

			AuthTreeDto treeNode = new AuthTreeDto(resourceName, id, parentId);

			if (Objects.equals(resource.getResourceType(), "0")){
				authTree.add(treeNode);
			}
			nodeMap.put(id, treeNode);
			nodeList.add(treeNode);
		}

		for (AuthTreeDto node : nodeList) {
			if (!Objects.equals(node.getParentId(), "0")) {
				AuthTreeDto authTreeDto = nodeMap.get(node.getParentId());
				if (UtilValidate.isNotEmpty(authTreeDto)) {
					List<AuthTreeDto> children = authTreeDto.getChildren();
					children.add(node);
				}
			}
		}
	}
}
